package utils

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"errors"
	"os"
	"strconv"
	"strings"
	"time"
)

// Header JWT头部结构
type Header struct {
	Alg string `json:"alg"`
	Typ string `json:"typ"`
}

// Claims JWT载荷结构
type Claims struct {
	UserID   int32  `json:"user_id"`
	Username string `json:"username"`
	Exp      int64  `json:"exp"` // 过期时间戳
	Iat      int64  `json:"iat"` // 签发时间戳
	Iss      string `json:"iss"` // 签发者
}

// 从环境变量获取配置，带默认值

// 获取JWT配置
func getJWTConfig() (secretKey string, tokenExpiryHours int, issuer string) {
	secretKey = getEnv("JWT_SECRET_KEY", "05VTcyEP98NsL5QjkapYOfKnSNSZeY52pAN6vhHkgaU")
	//令牌过期时间
	tokenExpiryHours = GetEnvInt("JWT_TOKEN_EXPIRY", 24)
	// 令牌的签发者
	issuer = getEnv("JWT_ISSUER", "yuan-ai-problem")
	return
}

// GenerateToken 生成JWT Token
func GenerateToken(userID int32, username string) (string, error) {
	//获取JWT配置
	secretKey, tokenExpiryHours, issuer := getJWTConfig()

	// 创建Header
	header := Header{
		Alg: "HS256",
		Typ: "JWT",
	}
	headerJSON, err := json.Marshal(header)
	if err != nil {
		return "", err
	}
	encodedHeader := base64.RawURLEncoding.EncodeToString(headerJSON)

	// 创建Claims
	claims := Claims{
		UserID:   userID,
		Username: username,
		Exp:      time.Now().Add(time.Duration(tokenExpiryHours) * time.Hour).Unix(),
		Iat:      time.Now().Unix(),
		Iss:      issuer,
	}
	claimsJSON, err := json.Marshal(claims)
	if err != nil {
		return "", err
	}
	encodedClaims := base64.RawURLEncoding.EncodeToString(claimsJSON)

	// 生成签名
	signatureBase := encodedHeader + "." + encodedClaims
	signature := HmacSHA256(signatureBase, secretKey)
	encodedSignature := base64.RawURLEncoding.EncodeToString(signature)

	// 组合完整Token
	return signatureBase + "." + encodedSignature, nil
}

// ParseToken 解析并验证JWT Token
func ParseToken(token string) (*Claims, error) {
	secretKey, _, _ := getJWTConfig()

	// 分割Token
	parts := strings.Split(token, ".")
	if len(parts) != 3 {
		return nil, errors.New("invalid token format")
	}

	encodedHeader, encodedClaims, encodedSignature := parts[0], parts[1], parts[2]

	// 验证签名
	expectedSignature := HmacSHA256(encodedHeader+"."+encodedClaims, secretKey)
	expectedEncodedSignature := base64.RawURLEncoding.EncodeToString(expectedSignature)
	if encodedSignature != expectedEncodedSignature {
		return nil, errors.New("invalid signature")
	}

	// 解码Claims
	claimsJSON, err := base64.RawURLEncoding.DecodeString(encodedClaims)
	if err != nil {
		return nil, err
	}

	var claims Claims
	if err := json.Unmarshal(claimsJSON, &claims); err != nil {
		return nil, err
	}

	// 验证过期时间
	now := time.Now().Unix()
	if claims.Exp < now {
		return nil, errors.New("token expired")
	}

	return &claims, nil
}

// hmacSHA256 使用HMAC-SHA256算法生成签名
func HmacSHA256(data, key string) []byte {
	h := hmac.New(sha256.New, []byte(key))
	h.Write([]byte(data))
	return h.Sum(nil)
}
func getEnv(key, defaultValue string) string {
	value := os.Getenv(key)
	if value == "" {
		return defaultValue
	}
	return value
}

// 从环境变量获取配置，转为int类型
func GetEnvInt(key string, defaultValue int) int {
	value := os.Getenv(key)
	if value == "" {
		return defaultValue
	}
	intValue, err := strconv.Atoi(value)
	if err != nil {
		return defaultValue
	}
	return intValue
}
